package com.hello.rabbitlistener;

import com.Constants;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;


import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpMessageHeaderAccessor;

import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.support.MessageHeaderAccessor;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * 这是消费者
 */
@Component
public class ConsumerRabbitListener {

    /**
     *  实践建议:一般一个队列就只用一个RabbitListener修饰的方法处理,
     *  如果想依据数据类型用不同的方法处理,请用RabbitHandler的形式
     *
     *  消息消费的线程池只有一个.(启用logback日志可以看出来)
     *
     * 一个RabbitListener修饰的方法就会产生一个新的channel,但connection只有一个.
     * 多个RabbitListener修饰的方法默认是以轮询的方式来接收消息
     *
     *  当有多个RabbitListener时(假定为m),这些被RabbitListener修饰的方法都会默认以轮询的方式接受消息
     *  如果在配置RabbitListenerContainerFactory时指定了并发消费者数量(假定为n),那么就相当于有m* n个消费者轮询消费消息
     *
     *  注意： ****RabbitListener注解中指定一个不存在的队列时是会报错的****
     * @param msg
     */
    @RabbitListener(queues = Constants.QUEUE_NAME)
    public void receive(String msg) {
        System.out.println("receive111:Thread.currentThread().getName() = " + Thread.currentThread().getName());
        System.out.println("msg = " + msg );
        System.out.println("===============================================================================");
    }


  /*  @RabbitListener(queues = Constants.QUEUE_NAME)
    public void receive2(String msg) {
        System.out.println("receive222:Thread.currentThread().getName() = " + Thread.currentThread().getName());
        System.out.println("msg = " + msg );
        System.out.println("===============================================================================");
    }*/

    //region     此方法与receiveWithConsumerTagForConcurrentConsumer合作,在有2个RabbitListener以及配置了并发消费者为2时,演示并发消费者用的

    /*@RabbitListener(queues = Constants.QUEUE_NAME)
    public void receiveWithConsumerTagForConcurrentConsumer(Message message) {
        System.out.println("receive11111:Thread.currentThread().getName() = " + Thread.currentThread().getName());
        System.out.println("header h1: " + message.getMessageProperties().getHeaders().get("h1"));
        System.out.println("message properties [content_type]:" + message.getMessageProperties().getContentType());

        String msg = new String(message.getBody(), StandardCharsets.UTF_8);
        System.out.println("msg = " + msg + " consumerTag:" + message.getMessageProperties().getConsumerTag());
        System.out.println("===============================================================================");
    }*/


/*    @RabbitListener(queues = Constants.QUEUE_NAME)
    public void receiveWithConsumerTagForConcurrentConsumer2(Message message) {
        System.out.println("receive22222:Thread.currentThread().getName() = " + Thread.currentThread().getName());
       // System.out.println("header h1: " + message.getMessageProperties().getHeaders().get("h1"));
        //System.out.println("message properties [content_type]:" + message.getMessageProperties().getContentType());

        String msg = new String(message.getBody(), StandardCharsets.UTF_8);
        System.out.println("msg = " + msg + " consumerTag:" + message.getMessageProperties().getConsumerTag());
        System.out.println("===============================================================================");
    }*/
    //endregion

    /**
     * 下面的方法用来说明接收方法可以允许的参数类型以及一些注解，见RabbitListener注解
     * 与上面的方法不要同时存在
     *
     * 默认的消息转换器只支持3种：字节数组，字符串，实现了Serializable接口的类型
     * Channel是com.rabbitmq.client.Channel 不是com.rabbitmq.client.AMQP.Channel类型
     * @param msg
     */
/*    @RabbitListener(queues = Constants.QUEUE_NAME)
    public void receiveMessage(Message msg,
                               @Payload String data,
                               @Header("h1") String h1,
                               @Headers Map<String,Object> headers,
                               Channel channel,
                               org.springframework.messaging.Message<String> msg2,
                               MessageHeaders msgHeaders,
                               MessageHeaderAccessor headerAccessor,
                               AmqpMessageHeaderAccessor amqpMessageHeaderAccessor) {
        System.out.println("receive2:Thread.currentThread().getName() = " + Thread.currentThread().getName());
        System.out.println("msg = " + new String(msg.getBody()));
        //msg.getMessageProperties().getHeader()
        //你可以在管理界面输入消息属性，点击？就可以知道有哪些有效地属性名，在MessageProperties有对应的getter，setter方法
        System.out.println("msg.getMessageProperties().getContentType() = " + msg.getMessageProperties().getContentType());
        System.out.println("msg2 = " + new String(msg2.getPayload()));
        System.out.println("data = " + data);
        System.out.println("h1 = " + h1);
        System.out.println("headers = " + headers);
        System.out.println("channel = " + channel);
        System.out.println("msgHeaders = " + msgHeaders);
        System.out.println("headerAccessor = " + headerAccessor);
        System.out.println("amqpMessageHeaderAccessor = " + amqpMessageHeaderAccessor);
    }*/

/*    @RabbitListener(queues = Constants.QUEUE_NAME)
    public String rpc(String hello) {
        System.out.println("监听者接收到了： = " + hello);
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return hello + " from listener's reply";
    }*/

}
